﻿#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>

//strlen strcpy strcat strcmp strstr strtok 
//struct union 联合enum
//realloc calloc malloc free
//perror typedef static extain

//malloc的使用
//int main()
//{
//	int* p = (int*)malloc(10 * sizeof(int));
//	if (p == NULL)
//	{
//		perror("malloc");
//		return 1;
//	}
//	//使用
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		*(p + i) = i;
//	}
//
//	int* str = (int*)realloc(p, 15 * sizeof(int));
//	if (str == NULL)
//	{
//		perror("realloc");
//		return 1;
//	}
//	else
//	{
//		p = str;
//	}
//
//	//使用
//	for (i = 0; i < 15; i++)
//	{
//		*(p + i) = i;
//	}
//	for (i = 0; i < 15; i++)
//	{
//		printf("%d ", *(p + i));
//	}
//
//	//释放
//	free(p);
//	p = NULL;
//
//	return 0;
//}

//柔性数组
//struct St
//{
//	char c;
//	int n;
//	int arr[0];
//};

//int main()
//{
//	struct St* p = (struct St*)malloc(sizeof(struct St) + 10 * sizeof(int));
//	if (p == NULL)
//	{
//		perror("malloc");
//		return 1;
//	}
//	//使用
//	p->c = 'w';
//	p->n = 250;
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		p->arr[i] = i;
//	}
//
//	//realloc调整
//	struct St* str = (struct St*)realloc(p, sizeof(struct St) + 15 * sizeof(int));
//	if (str == NULL)
//	{
//		perror("realloc");
//		return 1;
//	}
//	else
//	{
//		p = str;
//	}
//	for (i = 0; i < 15; i++)
//	{
//		p->arr[i] = i;
//	}
//	for (i = 0; i < 15; i++)
//	{
//		printf("%d ", p->arr[i]);
//	}
//	//释放
//	free(p);
//	p == NULL;
//
//	return 0;
//}


struct St
{
	char c;
	int n;
	int* arr;
};

int main()
{
	struct St* p = (struct St*)malloc(sizeof(struct St));
	if (p == NULL)
	{
		perror("malloc1");
		return 1;
	}
	p->arr = (int*)malloc(10 * sizeof(int));
	if (p->arr == NULL)
	{
		perror("malloc2");
		return 1;
	}
	//使用
	p->c = 'q';
	p->n = 300;
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		p->arr[i] = i;
	}
	//realloc调整
	int* str = (int*)realloc(p->arr, 15 * sizeof(int));
	if (str == NULL)
	{
		perror("realloc");
		return 1;
	}
	else
	{
		p->arr = str;
	}
	//使用
	for (i = 0; i < 15; i++)
	{
		p->arr[i] = i;
	}
	for (i = 0; i < 15; i++)
	{
		printf("%d ", p->arr[i]);
	}
	//释放
	free(p->arr);
	p->arr = NULL;
	free(p);
	p = NULL;

	return 0;
}
//
//struct S
//{
//	int a1;
//	int a2;
//	int a3;
//	
//	union 
//	{
//		struct 
//		{
//			char c1[20];
//			char c2[20];
//			int c3;
//		}s1;
//
//		struct
//		{
//			char d1[30];
//		}s2;
//
//		struct
//		{
//			char d1[30];
//			char d2[20];
//			int d3;
//		};
//	}U;
//};
//int main()
//{
//	return 0;
//}

//void GetMemory(char* p)//传递的地址，所以用指针接收
//{
//	p = (char*)malloc(100);
//	//p = malloc返回的地址
//	//函数调用完malloc开辟的空间不会销毁
//	//但是p是形参 - 实参临时拷贝，调用p会销毁，并不能改变str的值
//
//}
//void Test(void)
//{
//	char* str = NULL;
//	GetMemory(str);//传值调用 - 传递的NULL这个值
//	strcpy(str, "hello world");//str = NULL,当去访问NULL地址，并且使用，程序会崩溃
//	printf(str);
//}
//int main()
//{
//	Test();
//	return 0;
//}
//请问运⾏Test 函数会有什么样的结果？//程序崩溃


//修改
char* GetMemory()//传递的地址，所以用指针接收
{
	char *p = (char*)malloc(100);
	return p;
	//p = malloc返回的地址
	//函数调用完malloc开辟的空间不会销毁
	//但是p是形参 - 实参临时拷贝，调用p会销毁，并不能改变str的值

}
void Test(void)
{
	char* str = NULL;
	str = GetMemory();//传值调用 - 传递的NULL这个值
	strcpy(str, "hello world");//str = NULL,当去访问NULL地址，并且使用，程序会崩溃
	printf(str);
}
int main()
{
	Test();
	return 0;
}


char* GetMemory(void)
{
	char p[] = "hello world";//函数调用结束，这块空间销毁，一但把数组首元素的地址反回去，并接收，会成为野指针
	return p;
}
void Test(void)
{
	char* str = NULL;
	str = GetMemory();//str变成野指针
	printf(str);//并去访问使用
}
int main()
{
	Test();
	return 0;
}
请问运⾏Test 函数会有什么样的结果？//随机值



void GetMemory(char** p, int num)
{
	*p = (char*)malloc(num);
	//没有判断malloc开辟失败就使用
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str, 100);
	strcpy(str, "hello");
	printf(str);
}
int main()
{
	Test();
	return 0;
}
